let _Vue = null ;

export default class VueRouter {
  static install (Vue) {
    //1.判断当前插件是否已经安装
    if(VueRouter.install.installed) {
      return 
    } 

    VueRouter.install.installed = true ;

    //2.把Vue构造函数记录到全局变量中,方便在将来在VUE实例方法中使用 vue构造函数，例如，在创建组件时需要调用Vue.component
    _Vue = Vue ;

    //3.把创建vue实例时传入的router对象注入到所有Vue实例上，this.$router就是此时挂载到vue实例上的，且所有组件都是Vue实例
    _Vue.mixin({
      beforeCreate () {
        if (this.$options.router) { //组件没有router属性
          _Vue.prototype.$router = this.$options.router ;
          // this.init() ;
          this.$options.router.init(); 
        }

      }
    })
  }
  constructor (options) {
    this.options = options ;
    this.routerMap =  {};
    this.data = _Vue.observable({
      current: '/'
    }) //current 用来存储当前的路由地址，默认情况下是/;
  }

  init () {
    this.createCurrentMap();
    this.initComponents(_Vue) ;
    this.initEvent()
  }

  createCurrentMap () {
    //遍历所有的路由规则，把路由规则解析成键值对的形式，存储到routeMap中
    this.options.routes.forEach(route => {
      this.routerMap[route.path] =  route.component ;
    });
  }

  //创建组件router-link , router-view
  initComponents (Vue) {
    Vue.component('router-link', {
      props:{
        to: String
      } ,
      render (h) {
        return h('a',{
          attr: { 
            href: '#'+ this.to
          },
          on: {
            click: this.clickHandler
          }, 
        },[this.$slots.default])
      },

      methods: {
        clickHandler (e) { 
          //1.改变地址栏的路由地址，不向服务器发送请求
            // .pushState有三个参数，data--将来触发popstate事件时，传给popstate的参数,
            // title----网页标题，
            // url--超链接跳转的地址
          //2.更新视图 
          history.pushState({},'',this.to); //history模式下

          this.$router.data.current = this.to ; //修改当前路由的地址为this.to ,data是响应式数据，它的改变会重新加载对应的组件，并将其渲染到视图上； 
          // this指向的是router-link组件，因为注册插件时，$router就挂载到了Vue的构造函数的原型属性上，所以在vue的实例中(router-link组件也是Vue实例)可以直接访问到$router；

          e.preventDefault();  // 默认情况下会刷新浏览器，即默认情况下会向服务器发送请求
        }
      }
      // template: '<a :href="to"><slot></slot></a>'
    }); 
    const self = this ;
    Vue.component('router-view', { 
      render (h) {
        const component = self.routerMap[self.data.current] ;
        return h(component) 
      }
    })

  }

  // 浏览器的前进、后推按钮时的响应事件
  // 点击前进、后退时，即历史发生变化的时候，要去加载当前地址栏中的地址对应的组件，并将它渲染出来
  //调用pushState或者replaceState的时候不会触发popstate
   initEvent() { 
    window.addEventListener('popstate',()=>{
      this.data.current = window.location.pathname ;
    });
  }

}